#include <iostream>
using namespace std;
// (1)号函数
void func(int a, int b)
{
    cout << "#1 " << a << " " << b << endl;
}
// (2)号函数
void func(char a, int b, float c)
{
    cout << "#2 " << a << " " << b << " " << c << endl;
}

// (3)号函数
void func(char a, long b, double c)
{
    cout << "#3 " << a << " " << b << " " << c << endl;
}

int main()
{
    short n = 99;
    func('@', n, 99);
    func('@', n, 99.5);
    return 0;
}

/* 分析：

函数原型func(int, int)只有两个参数，而函数调用有三个参数，很容易看出来不匹配，在初次筛选时就会被过滤掉，接下来我们只讨论(2)(3)函数原型。

1) 先来看第一个函数调用。如果只考虑第一个实参'@'，那么(2)(3)两个函数都能够精确匹配，谁也不比谁优秀，是平等的；
如果只考虑第二个实参n，对于(2)，需要把 short 提升为 int（类型提升），对于(3)，需要把 short 转换为 long（类型转换），
类型提升的优先级高于类型转换，所以(2)胜出；如果只考虑第三个实参99，(2)(3)都要进行类型转换，没有哪一个能胜出，它们是平等的。

从整体上看，(2)(3)在第一、三个实参的匹配中是平等的，但(2)在第二个实参的匹配中胜出，也就是说，(2)对每个实参的匹配都不劣于(3)，但有一个实参的匹配优于(3)，
所以(2)最终脱颖而出，成为被调用函数。

2) 再来看第二个函数调用。只考虑第一个实参时(2)(3)是平等的，没有谁胜出；只考虑第二个实参时②胜出；只考虑第三个实参时，
(2)需要类型转换，(3)能够精确匹配，精确匹配的优先级高于类型转换，所以(3)胜出。

从整体上看，(2)(3)在第一个实参的匹配中是平等的，(2)在第二个实参的匹配中胜出，(3)在第三个实参的匹配中胜出，它们最终“打成了平手”，
分不清孰优孰劣，所以编译器不知道如何抉择，会产生二义性错误。
*/